package com.xiyuan.smartutils.client.domain;

import com.xiyuan.smartutils.Files;
import com.xiyuan.smartutils.StrUtils;
import com.xiyuan.smartutils.Validates;
import com.xiyuan.smartutils.constants.HttpConstants;

import java.io.*;


/**
 * 表单文件对象
 *
 * @author xiyuan-lgz 2022-10-08 @version 1.0.0 新建或整理
 */
public class FileItem implements HttpConstants {
    private static final String DEFAULT_MIME_TYPE = _APPLICATION_OCTET_STREAM_;
    
    private String fileName;
    private byte[] content;
    private File file;
    private String mimeType = DEFAULT_MIME_TYPE;
    
    /**
     * @param file 本地文件
     */
    public FileItem(File file) {
        this(file.getName(), file);
    }
    
    /**
     * @param content 文件内容
     */
    public FileItem(byte[] content) {
        this.content = content;
    }
    
    /**
     * @param fileName 文件名称
     * @param content  文件内容
     */
    public FileItem(String fileName, byte[] content) {
        this(fileName, content, null);
    }
    
    /**
     * @param fileName 文件名称
     * @param content  文件内容
     * @param mimeType 文件类型
     */
    public FileItem(String fileName, byte[] content, String mimeType) {
        this.fileName = StrUtils.trim(fileName);
        this.content = content;
        this.setMimeType(mimeType);
    }
    
    /**
     * @param fileName 文件名称
     * @param file     本地文件对象
     */
    public FileItem(String fileName, File file) {
        this.file = file;
        if (fileName == null && StrUtils.trim(fileName).length() == 0) {
            fileName = file.getName();
        }
        
        this.fileName = StrUtils.trim(fileName);
        if (file == null) {
            return;
        }
        this.setMimeType(Files.getMimeType(file));
    }
    
    
    public String getMimeType() {
        return mimeType;
    }
    
    public void setMimeType(String mimeType) {
        mimeType = StrUtils.trim(mimeType);
        this.mimeType = Validates.isNotBlank(mimeType) ? mimeType : _APPLICATION_OCTET_STREAM_;
    }
    
    public String getFileName() {
        return fileName;
    }
    
    public void setFileName(String fileName) {
        this.fileName = StrUtils.trim(fileName);
    }
    
    /**
     * write file data to output stream
     *
     * @param out 输出流
     * @return 文件长度
     * @throws IOException IO异常
     */
    public int write(OutputStream out) throws IOException {
        int length = 0;
        if (content != null) {
            length = content.length;
            if (out != null) {out.write(content);}
        } else if (file != null) {
            
            byte[] bytes = new byte[64 * KiB];
            try (InputStream in = new FileInputStream(file)) {
                int len;
                while ((len = in.read(bytes)) != -1) {
                    length += len;
                    if (out != null) {out.write(bytes, 0, len);}
                }
            }
        }
        
        return length;
    }
    
    public long length() throws IOException {
        if (content != null) {
            return content.length;
        }
        
        return content != null ? content.length : file == null ? 0 : file.length();
    }
}
